#include <arch/arch.h>
#include <task/task.h>
#include <fs/syscall.h>

#define SYS_OPEN   56
#define SYS_CLOSE  57


/* Trap handler 的一部分 */
uint64_t handle_syscall(struct pt_regs *regs)
{
    uint64_t sysno = regs->a7;  // 系统调用号
    uint64_t arg1  = regs->a0;
    uint64_t arg2  = regs->a1;
    uint64_t arg3  = regs->a2;
    uint64_t ret = 0;
    printk("[syscall] num=%lu arg1=0x%lx arg2=0x%lx arg3=0x%lx\n",
        sysno, arg1, arg2, arg3);
    printk("===================================================\n");
    uint64_t satp_val;
    __asm__ volatile("csrr %0, satp" : "=r"(satp_val));
    printk("SATP = 0x%lx\n", (unsigned long)satp_val);
    printk("===================================================\n");

    __asm__ volatile("csrs sstatus, %0" :: "r"(1UL <<18) : "memory");
    switch (sysno)
    {
        case SYS_OPEN:
            printk("sys_open\n");  
            ret = sys_open((const char *)arg1, arg2, arg3);
            break;
        case SYS_CLOSE:
            printk("sys_close\n");  
            ret = sys_close(arg1);
            break;
            case SYS_LSEEK:
            ret = sys_lseek(arg1, arg2, arg3);
            break;
        case SYS_READ:
            ret = sys_read(arg1, (void *)arg2, arg3);
            break;
        case SYS_WRITE:
            printk("ecall sys_write\n");
            ret = sys_write(arg1, (const void *)arg2, arg3);
            printk("ret = %d\n",ret);
            break;
        case SYS_IOCTL:
            ret = sys_ioctl(arg1, arg2, arg3);
            break;
        case SYS_READV:
            ret = sys_readv(arg1, (struct iovec *)arg2, arg3);
            break;
        case SYS_WRITEV:
            ret = sys_writev(arg1, (struct iovec *)arg2, arg3);
            break;
        case SYS_FORK:
            printk("ecall sys_fork\n");
            ret = task_fork(regs);
            printk("ret = %d\n",ret);
            break;
        case SYS_EXECVE:
            ret = task_execve((const char *)arg1, (char *const *)arg2, (char *const *)arg3);
            break;
        case SYS_EXIT:
            printk("ecall sys_exit\n");
            ret = task_exit((int64_t)arg1);
            printk("ret = %d\n",ret);
            break;
        case SYS_EXIT_GROUP:
            ret = task_exit((int64_t)arg1);
            break;
        case SYS_GETPID:
            ret = current_task->pid;
            break;
        case SYS_GETPPID:
            ret = current_task->ppid;
            break;
        case SYS_PRCTL:
            ret = sys_arch_prctl(arg1, arg2);
            break;
        case SYS_BRK:
            printk("ecall sys_brk\n");
            ret = sys_brk(arg1);
            printk("ret = %d\n",ret);
            break;
        default:
            printk("unknown syscall!!!!!!\n");  
            ret = (uint64_t)-ENOSYS;
            break;
    }

    /* 重要：不要在这里修改 regs->epc！只返回值 */
    return ret;
}

void syscall_init()
{
    
}
